﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ReadyApps.Common.Exceptions;
using ReadyApps.Data;
using ReadyApps.Data.Wiki;
using ReadyApps.Wiki;
using ReadyAppsTest.Data;

namespace ReadyAppsTest.Wiki
{
    [TestClass]
    public class WikiSecurityManagerTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Constructor Tests

        [TestMethod]
        [Description("Tests the normal operation of the constructor")]
        public void WikiSecurityManagerConstructorTest()
        {
            string username = string.Empty;
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);
            Assert.AreEqual(username, (string)targetWrapper.GetField("username"));
            Assert.AreEqual(roleManager, (TestWikiRoleManager)targetWrapper.GetField("roleManager"));
            Assert.AreEqual(dataProvider, (TestWikiDataProvider)targetWrapper.GetField("dataProvider"));
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        [Description("Tests for the null username exception")]
        public void WikiSecurityManagerConstructorNullUsernameTest()
        {
            string username = null;
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        [Description("Tests for the null role manager exception")]
        public void WikiSecurityManagerConstructorNullRoleManagerTest()
        {
            string username = "user";
            IWikiRoleManager roleManager = null;
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        [Description("Tests for the null data provider exception")]
        public void WikiSecurityManagerConstructorNullDataProviderTest()
        {
            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = null;
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
        }

        #endregion

        #region Policy Tests

        [TestMethod]
        [Description("Tests to ensure that edit permissions permission allows the user to view the page")]
        public void EditPermissionsImpliesViewPageRuleTest()
        {
            List<Tuple<EffectivePermissions, bool>> data = new List<Tuple<EffectivePermissions, bool>>();
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions(), false));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { EditPermissions = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = true, EditPermissions = true }, true));

            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            foreach (var testCase in data)
            {
                targetWrapper.SetField("effectivePermissions", testCase.Item1);
                Assert.AreEqual(testCase.Item2, target.CanViewPage);
            }
        }

        [TestMethod]
        [Description("Tests to ensure that the view page permission does not grant any more than viewing the page")]
        public void ViewPageDoesNotImplyEditPermissionsRuleTest()
        {
            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            targetWrapper.SetField("effectivePermissions", new EffectivePermissions() { ViewPage = true });
            Assert.IsFalse(target.CanEditPage);
            Assert.IsFalse(target.CanEditPermissions);
            Assert.IsFalse(target.CanManageRevisions);
        }

        [TestMethod]
        [Description("Tests to ensure edit page permissions grants view page permission")]
        public void EditPageImpliesViewPageRuleTest()
        {
            List<Tuple<EffectivePermissions, bool>> data = new List<Tuple<EffectivePermissions, bool>>();
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions(), false));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { EditPage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = true, EditPage = true }, true));

            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            foreach (var testCase in data)
            {
                targetWrapper.SetField("effectivePermissions", testCase.Item1);
                Assert.AreEqual(testCase.Item2, target.CanViewPage);
            }
        }

        [TestMethod]
        [Description("Tests to ensure manage revisions permissions grants view page permission")]
        public void ManageRevisionsImpliesViewPageRuleTest()
        {
            List<Tuple<EffectivePermissions, bool>> data = new List<Tuple<EffectivePermissions, bool>>();
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions(), false));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ManageRevisions = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = true, ManageRevisions = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = false, ManageRevisions = true }, true));

            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            foreach (var testCase in data)
            {
                targetWrapper.SetField("effectivePermissions", testCase.Item1);
                Assert.AreEqual(testCase.Item2, target.CanViewPage);
            }
        }

        [TestMethod]
        [Description("Tests to ensure manage publishing permissions grants view page permission")]
        public void ManagePublishingImpliesViewPageRuleTest()
        {
            List<Tuple<EffectivePermissions, bool>> data = new List<Tuple<EffectivePermissions, bool>>();
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions(), false));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ManagePublishing = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = true, ManagePublishing = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ViewPage = false, ManagePublishing = true }, true));

            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            foreach (var testCase in data)
            {
                targetWrapper.SetField("effectivePermissions", testCase.Item1);
                Assert.AreEqual(testCase.Item2, target.CanViewPage);
            }
        }

        [TestMethod]
        [Description("Tests to ensure manage publishing permissions grants edit page permission")]
        public void ManagePublishingImpliesEditPageRuleTest()
        {
            List<Tuple<EffectivePermissions, bool>> data = new List<Tuple<EffectivePermissions, bool>>();
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions(), false));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { EditPage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { ManagePublishing = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { EditPage = true, ManagePublishing = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { EditPage = false, ManagePublishing = true }, true));

            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            foreach (var testCase in data)
            {
                targetWrapper.SetField("effectivePermissions", testCase.Item1);
                Assert.AreEqual(testCase.Item2, target.CanEditPage);
            }
        }

        [TestMethod]
        [Description("Tests to ensure create page privileges grants edit page permission")]
        public void CreatePageImpliesEditPageRuleTest()
        {
            List<Tuple<EffectivePermissions, bool>> data = new List<Tuple<EffectivePermissions, bool>>();
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions(), false));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { EditPage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { CreatePage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { EditPage = true, CreatePage = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { EditPage = false, CreatePage = true }, true));

            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            foreach (var testCase in data)
            {
                targetWrapper.SetField("effectivePermissions", testCase.Item1);
                Assert.AreEqual(testCase.Item2, target.CanEditPage);
            }
        }

        [TestMethod]
        [Description("Tests to ensure create folder privileges grants create page privileges")]
        public void CreateFolderImpliesCreatePageRuleTest()
        {
            List<Tuple<EffectivePermissions, bool>> data = new List<Tuple<EffectivePermissions, bool>>();
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions(), false));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { CreatePage = true, CreateFolder = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { CreatePage = true, CreateFolder = false }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { CreatePage = false, CreateFolder = true }, true));
            data.Add(new Tuple<EffectivePermissions, bool>(new EffectivePermissions() { CreatePage = false, CreateFolder = false }, false));

            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            foreach (var testCase in data)
            {
                targetWrapper.SetField("effectivePermissions", testCase.Item1);
                Assert.AreEqual(testCase.Item2, target.CanCreatePage);
            }
        }

        #endregion

        #region Public Method Tests

        [TestMethod]
        [Description("Tests for proper view authorization based on effective permissions")]
        public void IsWikiPageModeAuthorizedTest()
        {
            // Permissions, Mode, Result
            List<Tuple<EffectivePermissions, WikiPageMode, bool>> testData = new List<Tuple<EffectivePermissions, WikiPageMode, bool>>();

            // Check for all negative results with default permissions
            foreach (var pageMode in Enum.GetValues(typeof(WikiPageMode)))
            {
                testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                    new EffectivePermissions(),
                    (WikiPageMode)pageMode, false));
            }

            // Check each permission with its associated views
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ViewPage = true },
                WikiPageMode.ViewPage, true));

            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { EditPage = true },
                WikiPageMode.EditPage, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { EditPage = true },
                WikiPageMode.ViewPage, true));

            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { CreatePage = true },
                WikiPageMode.CreatePage, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { CreatePage = true },
                WikiPageMode.ViewPage, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { CreatePage = true },
                WikiPageMode.EditPage, true));

            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { CreateFolder = true },
                WikiPageMode.CreatePage, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { CreateFolder = true },
                WikiPageMode.ViewPage, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { CreateFolder = true },
                WikiPageMode.EditPage, true));

            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { EditPermissions = true },
                WikiPageMode.EditPermissions, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { EditPermissions = true },
                WikiPageMode.ViewPage, true));

            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManageRevisions = true },
                WikiPageMode.PageSettings, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManageRevisions = true },
                WikiPageMode.ViewRevisionList, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManageRevisions = true },
                WikiPageMode.ViewPageRevision, true));

            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManagePublishing = true },
                WikiPageMode.PageSettings, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManagePublishing = true },
                WikiPageMode.ViewPage, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManagePublishing = true },
                WikiPageMode.ViewPagePending, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManagePublishing = true },
                WikiPageMode.EditPage, true));

            // Check that no other privileges grant edit permissions privileges
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ViewPage = true },
                WikiPageMode.EditPermissions, false));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { EditPage = true },
                WikiPageMode.EditPermissions, false));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { CreatePage = true },
                WikiPageMode.EditPermissions, false));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { CreateFolder = true },
                WikiPageMode.EditPermissions, false));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManageRevisions = true },
                WikiPageMode.EditPermissions, false));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ManagePublishing = true },
                WikiPageMode.EditPermissions, false));

            // Test some non-overlapping privileges
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ViewPage = true },
                WikiPageMode.EditPage, false));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { EditPermissions = true },
                WikiPageMode.ViewPage, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { EditPermissions = true },
                WikiPageMode.EditPage, false));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ViewPage = true, EditPermissions = true },
                WikiPageMode.ViewPage, true));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ViewPage = true, EditPermissions = true },
                WikiPageMode.EditPage, false));
            testData.Add(new Tuple<EffectivePermissions, WikiPageMode, bool>(
                new EffectivePermissions() { ViewPage = true, EditPermissions = true },
                WikiPageMode.EditPermissions, true));

            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            bool actual;
            foreach (var testCase in testData)
            {
                targetWrapper.SetField("effectivePermissions", testCase.Item1);
                actual = target.IsWikiPageModeAuthorized(testCase.Item2);
                Assert.AreEqual(testCase.Item3, actual, string.Format(
                    "Failed on Permissions = {0}, Mode = {1}, Expected = {2}, Actual = {3}",
                    testCase.Item1, testCase.Item2, testCase.Item3, actual));
            }
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidEnumerationValueException))]
        [Description("Tests for proper throwing of invalid enumeration values")]
        public void IsWikiPageModeAuthorizedInvalidTest()
        {
            string username = "user";
            IWikiRoleManager roleManager = new TestWikiRoleManager();
            IWikiDataProvider dataProvider = new TestWikiDataProvider();
            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            target.IsWikiPageModeAuthorized((WikiPageMode)1000);
        }

        [TestMethod]
        [Description("Tests for the proper permissions being applied to a non-security enabled site")]
        public void DeterminePagePermissionsUnsecuredTest()
        {
            string username = string.Empty;
            TestWikiRoleManager roleManager = new TestWikiRoleManager();
            TestWikiDataProvider dataProvider = new TestWikiDataProvider();

            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            bool securityEnabled = false;
            int pageID = 1;
            target.DeterminePagePermissions(securityEnabled, pageID);
            Assert.AreEqual(EffectivePermissions.NonSecurityEnabledPermissions,
                (EffectivePermissions)targetWrapper.GetField("effectivePermissions"));
            Assert.AreEqual(0, dataProvider.GetPagePermissions_pageID);
        }

        [TestMethod]
        [Description("Tests for the proper control flow for a security enabled site with page-specific permissions")]
        public void DeterminePagePermissionsSecuredPageSpecificTest()
        {
            string username = "user";
            int pageID = 3;
            TestWikiRoleManager roleManager = new TestWikiRoleManager();
            TestWikiDataProvider dataProvider = new TestWikiDataProvider();

            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);

            dataProvider.GetPagePermissions_ReturnValue = new PermissionSet();
            dataProvider.GetPagePermissions_pageSpecificPermissions = true;
            dataProvider.GetFolderPermissionsForPage_ReturnValue = new PermissionSet();

            target.DeterminePagePermissions(true, pageID);

            Assert.AreEqual(pageID, dataProvider.GetPagePermissions_pageID);
            Assert.AreEqual(pageID, dataProvider.GetFolderPermissionsForPage_pageID);
        }

        [TestMethod]
        [Description("Tests for the proper control flow for a security enabled site without page-specific permissions")]
        public void DeterminePagePermissionsSecuredSingleRoleTest()
        {
            string username = "user";
            int pageID = 4;
            TestWikiRoleManager roleManager = new TestWikiRoleManager();
            TestWikiDataProvider dataProvider = new TestWikiDataProvider();

            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);

            dataProvider.GetPagePermissions_ReturnValue = new PermissionSet();
            dataProvider.GetPagePermissions_pageSpecificPermissions = false;
            dataProvider.GetFolderPermissionsForPage_ReturnValue = new PermissionSet();

            target.DeterminePagePermissions(true, pageID);

            Assert.AreEqual(pageID, dataProvider.GetPagePermissions_pageID);
            Assert.AreEqual(0, dataProvider.GetFolderPermissionsForPage_pageID);
        }

        [TestMethod]
        [Description("Tests the IsSameUser method for proper comparison results")]
        public void IsSameUserTest()
        {
            // SecManUser, TestUser, Result
            List<Tuple<string, string, bool>> testCases = new List<Tuple<string, string, bool>>();
            testCases.Add(new Tuple<string, string, bool>("user", "user", true));
            testCases.Add(new Tuple<string, string, bool>("USER", "user", true));
            testCases.Add(new Tuple<string, string, bool>(string.Empty, "user", false));
            testCases.Add(new Tuple<string, string, bool>("user", string.Empty, false));
            testCases.Add(new Tuple<string, string, bool>(" user", "user", true));
            testCases.Add(new Tuple<string, string, bool>("user", " user", true));
            testCases.Add(new Tuple<string, string, bool>("user ", "user", true));
            testCases.Add(new Tuple<string, string, bool>("user", "user ", true));

            TestWikiRoleManager roleManager = new TestWikiRoleManager();
            roleManager.IsUserAuthenticated = true; // By-pass the debugging assertion
            TestWikiDataProvider dataProvider = new TestWikiDataProvider();

            WikiSecurityManager target = new WikiSecurityManager(string.Empty, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            bool actual;
            foreach (var testCase in testCases)
            {
                try
                {
                    targetWrapper.SetField("username", testCase.Item1);
                    actual = target.IsSameUser(testCase.Item2);
                    Assert.AreEqual(testCase.Item3, actual, string.Format(
                        "Failed on SecManUser = {0}, TestUser = {1}, Expected = {2}, Actual = {3}",
                        testCase.Item1, testCase.Item2, testCase.Item3, actual));
                }
                catch (Exception ex)
                {
                    Assert.Fail(string.Format(
                        "Failed on SecManUser = {0}, TestUser = {1}, Expected = {2}, Exception = {3}",
                        testCase.Item1, testCase.Item2, testCase.Item3, ex));
                }
            }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        [Description("Tests the IsSameUser method for null username parameter")]
        public void IsSameUserNullUsernameTest()
        {
            TestWikiRoleManager roleManager = new TestWikiRoleManager();
            roleManager.IsUserAuthenticated = true; // By-pass the debugging assertion
            TestWikiDataProvider dataProvider = new TestWikiDataProvider();

            WikiSecurityManager target = new WikiSecurityManager(string.Empty, dataProvider, roleManager);

            target.IsSameUser(null);
        }

        #endregion

        #region Private Method Tests

        [TestMethod]
        public void GetEffectivePermissionsPageTest()
        {
            string username = "user";
            TestWikiRoleManager roleManager = new TestWikiRoleManager();
            TestWikiDataProvider dataProvider = new TestWikiDataProvider();

            WikiSecurityManager target = new WikiSecurityManager(username, dataProvider, roleManager);
            PrivateObject targetWrapper = new PrivateObject(target);

            roleManager.UserIsInRole = true;
            PermissionSet pagePerms = new PermissionSet();
            RolePrivileges pagePrivs = pagePerms.AddRole("role1");
            pagePrivs.Privileges.ViewPage = true;
            pagePrivs.Privileges.CreatePage = true;
            PermissionSet folderPerms = new PermissionSet();
            RolePrivileges folderPrivs = folderPerms.AddRole("role2");
            folderPrivs.Privileges.EditPage = true;
            folderPrivs.Privileges.CreateFolder = true;

            EffectivePermissions effectivePerms = (EffectivePermissions)targetWrapper.Invoke("GetEffectivePermissions", pagePerms, folderPerms);
            Assert.IsTrue(effectivePerms.ViewPage);
            Assert.IsTrue(effectivePerms.CreateFolder);
            Assert.IsFalse(effectivePerms.CreatePage);
            Assert.IsFalse(effectivePerms.EditPage);
        }

        #endregion
    }
}
